import React, { Component } from 'react';
import { Link } from 'react-router-dom';
import { message, Modal, Select } from 'antd';
import _ from 'lodash';
import { connect } from 'react-redux';
import moment from 'moment';
import PropTypes from 'prop-types';
import { addOneday } from '@api/task';
import { getAllDicts } from '@api/dict';
import '../../../oneday-detection/list/components/oneday-detection-modal/index.less';
import TaskCommonFields from '@components/task-common-fields';
import isClusterModel from '@components/is-cluster-model';
const prefixCls = 'oneday-modal';
const { Option } = Select;
const DICT_OPTIONS = [
  {
    name: '用户名字典',
    key: 'username'
  },
  {
    name: '密码字典',
    key: 'password'
  }
];

class WeakPasswordModal extends Component {
  static defaultState = {
    enableBuildInDict: false,
    enableWhiteList: false,
    runAt: {
      isRunAt: false,
      time: moment().format('YYYY-MM-DD HH:mm:ss')
    },
    urgent: false,
    ignoreIpsError: '',
    ignoreType: {
      whitelist: false,
      custom: false
    },
    customIgnoreTarget: [],
    timing: {},
    startAt: '',
    endAt: '',
    errorMsg: ''
  };

  constructor(props) {
    super(props);
    this.state = _.cloneDeep({
      ...WeakPasswordModal.defaultState,
      dictSelect: {},
      dictsGroups: {}
    });
  }

  static getDerivedStateFromProps(props) {
    if (!props.modalVisible) {
      return _.cloneDeep({ ...WeakPasswordModal.defaultState });
    }
    return null;
  }

  componentDidUpdate() {
    if (this.props.modalVisible && !this.checkSiteCount()) {
      message.warning('您选择的漏洞当前影响资产数皆为0，请更换检测目标');
      this.props.closeModal();
    }
  }

  componentDidMount() {
    getAllDicts().then(res => {
      const list = _.get(res, 'data.data.list', []);
      const dictsGroups = {};
      list.forEach(d => {
        dictsGroups[d._id] = [].concat(d.dicts);
      });
      const dictSelect = {};
      DICT_OPTIONS.forEach(({ key }) => {
        const hasDict = !_.isEmpty(dictsGroups[key]);
        let builtInDict = _.find(dictsGroups[key], 'isBuiltIn');
        builtInDict = hasDict && builtInDict ? builtInDict : {};
        dictSelect[key] = builtInDict._id || '';
      });
      this.setState({ dictsGroups, dictSelect });
    });
  }

  checkSiteCount = () => {
    let data = _.get(this.props, 'data', {});
    return _.get(data, 'affectedSiteCount.real') || _.get(data, 'affectedSiteCount.suspect');
  };

  handleChange = (value, option) => {
    const { dictSelect } = this.state;
    const type = _.get(option, 'props.type');
    if (type) {
      dictSelect[type] = value;
      this.setState({ dictSelect });
    }
  };

  onClickSubmit = async () => {
    const { modules, isCluster } = this.props;
    if (!modules.includes('detection')) {
      return message.info('演示版本不能下发任务，请联系ZoomEye BE团队获取正式版本');
    }
    await isClusterModel();
    let { _id, name } = this.props.data;
    let {
      enableBuildInDict,
      dictSelect,
      dictsGroups = {},
      timing: timeRange,
      ignoreType,
      startAt,
      endAt,
      customIgnoreTarget,
      errorMsg,
      scanNodes
    } = this.state;

    if (errorMsg) {
      message.warning(errorMsg);
      return;
    }

    const usernameDict = _.find(
      dictsGroups['username'] || [],
      d => d._id === _.get(dictSelect, 'username')
    );

    const passwordDict = _.find(
      dictsGroups['password'] || [],
      d => d._id === _.get(dictSelect, 'password')
    );
    let hasDict = !_.isEmpty(usernameDict) || !_.isEmpty(passwordDict);
    if (!hasDict) {
      return message.error('请选择系统默认字典或自定义字典');
    }

    const userNum = _.get(usernameDict, 'count', 0);
    const pwdNum = _.get(passwordDict, 'count', 0);

    const params = {
      name: `${name}_受影响的资产_${moment().format('YYYYMMDDHHmmss')}`,
      target: {
        queryType: 'affectedByOnedayDetail'
      },
      oneday: {
        queryType: 'list',
        onedayDetailOids: [_id]
      },
      enableBuildInDict: enableBuildInDict,
      isWeakPassTask: true
    };

    // 如果是集群 node默认为auto interface_type默认为'work'
    if (isCluster) {
      params.node = scanNodes;

      params.interface_type = 'work';
    } else {
      params.node = 'local';
    }

    const payload = {
      fields: params,
      dicts: { usernameDict, passwordDict }
    };

    let newIgnoreType = [];
    if (ignoreType.whitelist) {
      newIgnoreType.push('whiteList');
    }
    if (ignoreType.custom) {
      params.customIgnoreTarget = customIgnoreTarget;
      if (!customIgnoreTarget.length) {
        message.warning('勾选了自定义忽略目标，没有填写对应目标');
        return;
      }
      newIgnoreType.push('custom');
    }
    if (newIgnoreType.length) {
      params.ignoreType = newIgnoreType;
    }

    let timing = _.cloneDeep(timeRange);
    if (timing) {
      startAt && (timing.startAt = startAt.format('YYYY-MM-DD HH:mm:ss'));
      endAt && (timing.endAt = endAt.format('YYYY-MM-DD HH:mm:ss'));
      if (timing.dailyStart) {
        timing.dailyStart = timing.dailyStart.format('HH:mm');
      } else {
        delete timing.dailyStart;
      }
      if (timing.dailyEnd) {
        timing.dailyEnd = timing.dailyEnd.format('HH:mm');
      } else {
        delete timing.dailyEnd;
      }
      params.timing = timing;
    }

    this.setState({ isAdding: true });
    addOneday(payload)
      .then(() => {
        if (hasDict) {
          message.success(`本次检测包含自定义用户名 ${userNum} 条，密码 ${pwdNum} 条`);
        }
        message.success('下发检测成功');
        this.props.closeModal();
      })
      .catch(({ type, message: messageString }) => {
        if (type === 'parsed') {
          message.error(messageString);
        } else {
          message.error('下发检测失败');
        }
      })
      .finally(() => {
        this.setState({ isAdding: false });
      });
  };

  onCommonFieldChange = commonFields => {
    const fields = _.pick(commonFields, [
      'startAt',
      'endAt',
      'timing',
      'errorMsg',
      'priority',
      'ignoreType',
      'customIgnoreTarget',
      'scanNodes'
    ]);
    this.setState({ ...fields });
  };

  render() {
    const { isAdding, dictsGroups } = this.state;
    const { modalVisible = false, closeModal } = this.props;
    return (
      <Modal
        maskClosable={false}
        visible={modalVisible && this.checkSiteCount()}
        title="弱口令检测"
        okText="确定"
        width={600}
        closable={true}
        className={`${prefixCls}-modal`}
        onCancel={closeModal}
        onOk={this.onClickSubmit}
        confirmLoading={isAdding}
        destroyOnClose
      >
        {DICT_OPTIONS.map(({ name, key }) => {
          const hasDict = !_.isEmpty(dictsGroups[key]);
          const { dictSelect } = this.state;
          return (
            <div className={`${prefixCls}-item`} key={key}>
              <div className={`${prefixCls}-item-sub-title`}>{name}</div>
              <Select value={dictSelect[key]} style={{ width: 180 }} onChange={this.handleChange}>
                {hasDict &&
                  dictsGroups[key].map(dict => {
                    return (
                      <Option value={dict._id} type={key} key={dict._id}>
                        {dict.name}
                      </Option>
                    );
                  })}
              </Select>
            </div>
          );
        })}
        <div style={{ margin: '-15px 0 15px' }}>
          <Link to="/asset-config/dict-config">配置字典</Link>
        </div>
        <TaskCommonFields onCommonFieldChange={this.onCommonFieldChange} prefixCls={prefixCls} />
      </Modal>
    );
  }
}

WeakPasswordModal.propTypes = {
  closeModal: PropTypes.function,
  modalVisible: PropTypes.boolean,
  modules: PropTypes.array,
  data: PropTypes.object,
  isCluster: PropTypes.object
};

const mapStateToProps = state => {
  return {
    modules: _.get(state, 'auth.cert.modules', []),
    isCluster: _.get(state, 'auth.cert.is_cluster', false)
  };
};

export default connect(mapStateToProps)(WeakPasswordModal);
